import React, { useState, useEffect, useCallback } from 'react';
import Domino from './Domino';
import { generateDominoSet, shuffleArray } from '../utils/dominoUtils';
import '../styles/GameBoard.css';

function GameBoard() {
  const [dominoPile, setDominoPile] = useState([]); // 牌堆
  const [playedDominoes, setPlayedDominoes] = useState([]); // 存储已放置的骨牌链
  const [playerHand, setPlayerHand] = useState([]); // 存储玩家手牌
  const [aiHand, setAiHand] = useState([]); // 存储 AI 手牌
  const [leftEnd, setLeftEnd] = useState(null); // 链条左端可连接的点数
  const [rightEnd, setRightEnd] = useState(null); // 链条右端可连接的点数
  const [currentPlayer, setCurrentPlayer] = useState('player'); // 当前玩家: 'player' 或 'ai'
  const [message, setMessage] = useState(''); // 游戏提示信息
  const [gameOver, setGameOver] = useState(false); // 游戏是否结束
  const [playerCannotPlay, setPlayerCannotPlay] = useState(false); // 玩家是否无法出牌
  const [aiCannotPlay, setAiCannotPlay] = useState(false); // AI 是否无法出牌

  // 初始化游戏
  const initializeGame = useCallback(() => {
    const fullSet = generateDominoSet();
    const shuffledSet = shuffleArray(fullSet);
    setPlayerHand(shuffledSet.slice(0, 7));
    setAiHand(shuffledSet.slice(7, 14));
    setDominoPile(shuffledSet.slice(14));
    setPlayedDominoes([]);
    setLeftEnd(null);
    setRightEnd(null);
    setCurrentPlayer('player'); // 玩家先手
    setMessage('你的回合');
    setGameOver(false);
    setPlayerCannotPlay(false);
    setAiCannotPlay(false);
  }, []);

  // 初始化游戏状态
  const resetGameState = useCallback(() => {
    const fullSet = generateDominoSet();
    const shuffledSet = shuffleArray(fullSet);
    setPlayerHand(shuffledSet.slice(0, 7));
    setAiHand(shuffledSet.slice(7, 14));
    setDominoPile(shuffledSet.slice(14));
    setPlayedDominoes([]);
    setLeftEnd(null);
    setRightEnd(null);
    setCurrentPlayer('player'); // 玩家先手
    setMessage('你的回合');
    setGameOver(false);
    setPlayerCannotPlay(false);
    setAiCannotPlay(false);
    console.log("Game Initialized/Reset");
  }, []);

  // 组件加载时初始化游戏
  useEffect(() => {
    resetGameState();
  }, [resetGameState]);

  // 重新开始按钮的处理函数
  const handleRestart = () => {
    resetGameState();
  };

  // 检查玩家是否有可出的牌
  const checkPlayerPlayable = useCallback(() => {
    if (playerHand.length === 0) return false; // 手牌空了
    for (const domino of playerHand) {
      if (isDominoPlayable(domino)) {
        return true;
      }
    }
    return false;
  }, [playerHand, playedDominoes, leftEnd, rightEnd]);

  // 检查 AI 是否有可出的牌
  const checkAiPlayable = useCallback(() => {
    if (aiHand.length === 0) return false;
    for (const domino of aiHand) {
      if (isDominoPlayable(domino)) {
        return true;
      }
    }
    return false;
  }, [aiHand, playedDominoes, leftEnd, rightEnd]);

  // 检查游戏是否结束
  const checkGameOver = useCallback(() => {
    if (playerHand.length === 0) {
      setMessage('恭喜！你赢了！');
      setGameOver(true);
      return true;
    }
    if (aiHand.length === 0) {
      setMessage('AI 赢了！');
      setGameOver(true);
      return true;
    }
    // 检查僵局
    const playerCanPlay = checkPlayerPlayable();
    const aiCanPlay = checkAiPlayable();
    const pileEmpty = dominoPile.length === 0;

    if (pileEmpty && !playerCanPlay && !aiCanPlay) {
        setMessage('僵局！没人能出牌了。');
        setGameOver(true);
        // 可以根据手牌点数判断胜负
        return true;
    }

    const isPlayerStuck = !playerCanPlay && pileEmpty;
    const isAiStuck = !aiCanPlay && pileEmpty;

    setPlayerCannotPlay(isPlayerStuck);
    setAiCannotPlay(isAiStuck);

    return false;
  }, [playerHand, aiHand, dominoPile, checkPlayerPlayable, checkAiPlayable]);

  // 切换回合
  const switchTurn = useCallback(() => {
    // 切换前先检查一次，防止状态更新延迟导致错误判断
    if (checkGameOver()) {
        console.log("SwitchTurn: Game over check returned true.");
        return;
    }

    const nextPlayer = currentPlayer === 'player' ? 'ai' : 'player';
    setCurrentPlayer(nextPlayer);
    setMessage(nextPlayer === 'player' ? '你的回合' : 'AI 的回合');

    // 如果切换到 AI 且 AI 无法出牌且牌堆为空，则直接跳过
    if (nextPlayer === 'ai' && aiCannotPlay) {
        console.log("AI无法出牌且牌堆为空，跳过回合");
        setTimeout(() => switchTurn(), 500); // 短暂延迟后切回玩家
    }
    // 如果切换到玩家且玩家无法出牌且牌堆为空，则直接跳过
    if (nextPlayer === 'player' && playerCannotPlay) {
        console.log("玩家无法出牌且牌堆为空，跳过回合");
        setTimeout(() => switchTurn(), 500); // 短暂延迟后切回AI
    }

  }, [currentPlayer, checkGameOver, aiCannotPlay, playerCannotPlay]);

  // 检查骨牌是否可以在任何一端放置
  const isDominoPlayable = (domino) => {
    if (playedDominoes.length === 0) {
      return true; // 第一张牌总可以放置
    }
    // 检查是否匹配左端或右端
    return domino.top === leftEnd || domino.bottom === leftEnd || domino.top === rightEnd || domino.bottom === rightEnd;
  };

  // 检查是否可以放置骨牌 (保留原有逻辑，用于放置时判断具体位置和是否翻转)
  const canPlaceDomino = (domino, position) => {
    if (playedDominoes.length === 0) {
      return true; // 第一张牌总可以放置
    }
    // 检查是否需要翻转以及是否匹配
    if (position === 'left') {
      return domino.top === leftEnd || domino.bottom === leftEnd;
    }
    if (position === 'right') {
      return domino.top === rightEnd || domino.bottom === rightEnd;
    }
    return false;
  };

  // 放置骨牌的逻辑 (通用)
  const placeDomino = (dominoToPlace, hand, setHand, playerType) => {
    let position = null;
    let reversed = false;
    let canPlace = false;

    if (playedDominoes.length === 0) {
        position = 'start';
        canPlace = true;
    } else {
        // 尝试右边
        if (dominoToPlace.top === rightEnd) {
            position = 'right';
            reversed = false;
            canPlace = true;
        } else if (dominoToPlace.bottom === rightEnd) {
            position = 'right';
            reversed = true;
            canPlace = true;
        }
        // 如果右边不行，尝试左边
        if (!canPlace) {
            if (dominoToPlace.bottom === leftEnd) {
                position = 'left';
                reversed = false;
                canPlace = true;
            } else if (dominoToPlace.top === leftEnd) {
                position = 'left';
                reversed = true;
                canPlace = true;
            }
        }
    }

    if (!canPlace) {
        // 这个检查理论上不应该在这里触发，因为调用 placeDomino 前应该已确认可放置
        console.error(`${playerType} 尝试放置无法放置的牌?`, dominoToPlace);
        return false; // 不能放置
    }

    // 从手牌移除
    const indexInHand = hand.findIndex(d => d.id === dominoToPlace.id); // 假设 domino 有 id
    if (indexInHand === -1) {
        console.error("牌不在手中?", dominoToPlace, hand);
        return false;
    }
    const newHand = [...hand];
    newHand.splice(indexInHand, 1);
    setHand(newHand);

    // 准备要添加到链条的骨牌 (根据需要翻转)
    const finalDomino = reversed ? { ...dominoToPlace, top: dominoToPlace.bottom, bottom: dominoToPlace.top } : { ...dominoToPlace };

    // 更新链条和两端点数
    let newPlayedDominoes;
    if (position === 'start') {
        newPlayedDominoes = [finalDomino];
        setLeftEnd(finalDomino.top);
        setRightEnd(finalDomino.bottom);
    } else if (position === 'right') {
        newPlayedDominoes = [...playedDominoes, finalDomino];
        setRightEnd(finalDomino.bottom); // 右端更新为新牌的下半部分
    } else { // position === 'left'
        newPlayedDominoes = [finalDomino, ...playedDominoes];
        setLeftEnd(finalDomino.top); // 左端更新为新牌的上半部分
    }
    setPlayedDominoes(newPlayedDominoes);
    setMessage(''); // 清除提示信息
    console.log(`${playerType} 放置 ${dominoToPlace.top}-${dominoToPlace.bottom} 到 ${position}${reversed ? ' (翻转)' : ''}`);

    // 放置成功后检查游戏是否结束，然后切换回合
    if (!checkGameOver()) {
        setTimeout(() => switchTurn(), 500); // 延迟切换，给玩家观察时间
    }
    return true;
  };

  // 玩家放置骨牌的处理
  const handlePlaceDomino = (dominoToPlace, indexInHand) => {
    if (currentPlayer !== 'player' || gameOver) return; // 不是玩家回合或游戏结束

    if (!isDominoPlayable(dominoToPlace)) {
        setMessage('无法放置该骨牌，请尝试其他牌或抽牌');
        console.log('无法放置该骨牌');
        return;
    }

    // 使用通用放置逻辑，传入玩家的手牌和设置函数
    // 直接使用骨牌自带的 ID
    placeDomino(dominoToPlace, playerHand, setPlayerHand, '玩家');
  };

  // 从牌堆抽牌的逻辑 (通用)
  const drawDomino = (hand, setHand, playerType) => {
    if (dominoPile.length === 0) {
      setMessage('牌堆已空！');
      return false; // 抽牌失败
    }

    const newDominoPile = [...dominoPile];
    const drawnDomino = newDominoPile.shift(); // 从牌堆顶部取一张
    setDominoPile(newDominoPile);
    // generateDominoSet 应该已经为所有牌生成了 ID
    setHand([...hand, drawnDomino]);
    setMessage(''); // 清除提示信息
    console.log(`${playerType} 从牌堆抽取:`, drawnDomino);

    // 抽牌后检查游戏是否结束（比如僵局）
    if (checkGameOver()) return true;

    // 抽牌后立即切换回合
    setTimeout(() => switchTurn(), 500);
    return true; // 抽牌成功
  };

  // 玩家抽牌处理
  const handleDrawDomino = () => {
    if (currentPlayer !== 'player' || gameOver || dominoPile.length === 0) return;

    // 检查玩家是否真的需要抽牌（没有可出的牌）
    if (checkPlayerPlayable()) {
        setMessage('你还有可以出的牌，无需抽牌。');
        return;
    }

    drawDomino(playerHand, setPlayerHand, '玩家');
  };

  // AI 回合逻辑
  const aiTurn = useCallback(() => {
    if (gameOver) return;
    console.log("AI 回合开始");

    // 1. 查找可出的牌
    let playableDomino = null;
    let playableIndex = -1;
    for (let i = 0; i < aiHand.length; i++) {
      if (isDominoPlayable(aiHand[i])) {
        playableDomino = aiHand[i]; // 直接使用牌对象及其 ID
        playableIndex = i;
        break; // 简单 AI：找到第一张能出的就出
      }
    }

    // 2. 如果找到可出的牌，则出牌
    if (playableDomino) {
      console.log("AI 找到可出的牌:", playableDomino);
      placeDomino(playableDomino, aiHand, setAiHand, 'AI');
      return; // 出牌后结束 AI 回合
    }

    // 3. 如果没有可出的牌，且牌堆有牌，则抽牌
    if (dominoPile.length > 0) {
      console.log("AI 没有可出的牌，尝试抽牌");
      drawDomino(aiHand, setAiHand, 'AI');
      return; // 抽牌后结束 AI 回合
    }

    // 4. 如果没有可出的牌，牌堆也空了，则跳过回合
    console.log("AI 没有可出的牌，牌堆也空了，跳过回合");
    setMessage('AI 无牌可出，跳过回合');
    setAiCannotPlay(true); // 标记 AI 无法行动
    setTimeout(() => switchTurn(), 1000); // 延迟切换回合

  }, [aiHand, dominoPile, playedDominoes, leftEnd, rightEnd, gameOver, placeDomino, drawDomino, switchTurn, isDominoPlayable]);

  // 监听当前玩家变化，如果是 AI 则执行 AI 回合
  useEffect(() => {
    if (currentPlayer === 'ai' && !gameOver) {
      // 添加延迟，模拟 AI 思考
      const timeoutId = setTimeout(() => {
        aiTurn();
      }, 1500); // 1.5秒延迟

      return () => clearTimeout(timeoutId); // 清理 timeout
    }
  }, [currentPlayer, gameOver, aiTurn]);

  // 移除独立的 checkGameOver useEffect，将其移到操作后调用

  return (
    <div className="game-board-container">
      <h1>多米诺骨牌游戏 (人机对战)</h1>
      <button onClick={handleRestart} style={{ marginBottom: '10px' }}>重新开始</button>
      {message && <p className={`game-message ${gameOver ? 'game-over' : ''}`}>{message}</p>} {/* 显示游戏提示 */}
      <p>当前回合: {currentPlayer === 'player' ? '你' : 'AI'}</p>

      {/* AI 手牌区域 (简单显示数量) */}
      <div className="ai-hand">
          <h3>AI 手牌 ({aiHand.length}张)</h3>
          <div className="domino-list hidden">
              {aiHand.map((_, index) => (
                  <div key={`ai-hidden-${index}`} className="domino-container hidden-domino">
                      <div className="domino placeholder"></div>
                  </div>
              ))}
          </div>
      </div>

      <div className="played-area">
        <h3>场上骨牌 (左: {leftEnd ?? '-'}, 右: {rightEnd ?? '-'})</h3>
        <div className="domino-chain">
          {playedDominoes.map((domino, index) => (
            <Domino key={`played-${index}`} top={domino.top} bottom={domino.bottom} />
          ))}
          {playedDominoes.length === 0 && !message.includes('赢了') && <p>请从手牌中选择一张开始游戏</p>}
        </div>
      </div>

      <div className="player-hand">
        <h3>你的手牌 ({playerHand.length}张)</h3>
        <div className="domino-list">
          {playerHand.map((domino, index) => { // index 仍然可用，但主要用 domino.id
            const playable = isDominoPlayable(domino);
            const canClick = currentPlayer === 'player' && !gameOver && playable;
            return (
              <div
                key={domino.id} // 使用骨牌自带的 ID 作为 key
                className={`domino-container ${playable ? 'playable' : ''} ${!canClick ? 'disabled' : ''}`}
                onClick={() => canClick && handlePlaceDomino(domino, index)} // 传递原始 domino 对象
                title={playable ? "点击放置" : "无法放置"}
              >
                <Domino top={domino.top} bottom={domino.bottom} />
              </div>
            );
          })}
        </div>
      </div>

      <div className="game-actions">
        <button
          onClick={handleDrawDomino}
          disabled={currentPlayer !== 'player' || gameOver || dominoPile.length === 0 || checkPlayerPlayable() || playerCannotPlay}
          title={checkPlayerPlayable() ? "你还有可以出的牌" : (dominoPile.length === 0 ? "牌堆已空" : "从牌堆抽牌")}
        >
          从牌堆抽牌 ({dominoPile.length}张)
        </button>
        {/* 可以添加一个“跳过回合”按钮，仅在无法出牌且牌堆为空时可用 */}
        {playerCannotPlay && currentPlayer === 'player' && !gameOver && (
             <button onClick={switchTurn}>跳过回合</button>
        )}
      </div>
    </div>
  );
}

export default GameBoard;